package net.zigin.nhi.could.waste.service.impl;

import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.export.ExcelExportService;
import net.zigin.commons.util.*;
import net.zigin.nhi.could.waste.aop.LoginAspect;
import net.zigin.nhi.could.waste.dao.*;
import net.zigin.nhi.could.waste.model.SysRole;
import net.zigin.nhi.could.waste.util.*;
import net.zigin.nhi.could.waste.vo.*;
import net.zigin.nhi.could.waste.constants.CommonConstants;
import net.zigin.nhi.could.waste.dto.SysUserStaffDto;
import net.zigin.nhi.could.waste.exception.EpiCloudException;
import net.zigin.nhi.could.waste.model.SysUser;
import net.zigin.nhi.could.waste.service.SysRoleService;
import net.zigin.nhi.could.waste.service.SysUserService;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import net.zigin.nhi.could.waste.model.SysUserHospital;
import net.zigin.nhi.could.waste.service.SysUserHospitalService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/*#################################################################*
# 说明:以下代码通过哲勤代码生成工具自动生成    
# 工具:GeneratorCode
# 作者:mgw1986                                                  
# 生成时间:2021-9-7 19:08:58                                               
##################################################################*/


/**
 * SysUserHospital服务实现类
 *
 * @author mgw1986
 * @version V1.0
 * @ClassName: SysUserHospitalServiceImpl
 * @date 2021-9-7 19:08:58
 */
@Service
public class SysUserHospitalServiceImpl extends AbstractServiceImpl<SysUserHospital, String> implements SysUserHospitalService {
    @Autowired
    private SysUserHospitalMapper sysUserHospitalMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysRoleService sysRoleService;
    @Autowired
    private HospitalDepartMapper hospitalDepartMapper;

    @Override
    public BaseMapper<SysUserHospital, String> getMapper() {
        return sysUserHospitalMapper;
    }

    @Override
    public String getSysUserIdByHospitalBaseId(String hospitalBaseId) {
        return sysUserHospitalMapper.getSysUserIdByHospitalBaseId(hospitalBaseId);
    }

    @Override
    public String saveOrUpdate(SysUserStaffDto userStaffDto) {
        SysUserVo currentUser = sysUserService.getCurrentUser();
        userStaffDto.setHospitalBaseId(currentUser.getHospitalBaseId());
        AssertUtil.isNull(userStaffDto, "员工信息不能为空");
        if (!StringUtil2.isPhone(userStaffDto.getMobile())) {
            throw new EpiCloudException("手机号格式不正确！");
        }
        if (StringUtil.isNullOrEmpty(userStaffDto.getId())) {
            // 新增 先新增sysUser todo 校验手机号是否存在
            SysUser user = new SysUser(userStaffDto);
            sysUserService.checkMobileExist(userStaffDto.getMobile());
            sysUserMapper.insert(user);
            userStaffDto.setSysUserId(user.getId());
            SysUserHospital userHospital = new SysUserHospital(userStaffDto);
            sysUserHospitalMapper.insert(userHospital);
            if (!StringUtil.isNullOrEmpty(userStaffDto.getRoleId())) {
                List<String> roleIds = new ArrayList<>();
                roleIds.add(userStaffDto.getRoleId());
                sysRoleService.concatUser(roleIds, user.getId());
            }
            // 绑定基础角色 h001
            //sysRoleService.concatUser(userHospital.getSysUserId(), 1);
            return userHospital.getId();
        }
        // 编辑角色
        // 编辑 邮箱编辑不成功 todo 对sysUser进行编辑
        SysUser sysUser = sysUserMapper.selectByPrimaryKey(userStaffDto.getSysUserId());
        sysUser.setEmail(userStaffDto.getEmail());
        sysUser.setMobile(userStaffDto.getMobile());
        sysUserMapper.updateByPrimaryKeySelective(sysUser);
        SysUserHospital userHospital = new SysUserHospital(userStaffDto);
        sysUserHospitalMapper.updateByPrimaryKeySelective(userHospital);
        if (!StringUtil.isNullOrEmpty(userStaffDto.getRoleId())) {
            List<String> roleIds = new ArrayList<>();
            roleIds.add(userStaffDto.getRoleId());
            sysRoleService.concatUser(roleIds, userHospital.getSysUserId());
        }
        return userHospital.getId();
    }


    @Override
    public List<SysUserStaffVo> getList(SysUserStaffDto sysUserStaffDto) {
        Map<String, Object> paramMap = getUserStaffParam(sysUserStaffDto);
        if (sysUserStaffDto.getIsPage()) {
            return sysUserHospitalMapper.getInfoPageByCondition(paramMap);
        }
        return sysUserHospitalMapper.getInfoListByCondition(paramMap);
    }

    @Override
    public Integer getCount(SysUserStaffDto sysUserStaffDto) {
        Map<String, Object> paramMap = getUserStaffParam(sysUserStaffDto);
        return sysUserHospitalMapper.getCountByCondition(paramMap);
    }

    private Map<String, Object> getUserStaffParam(SysUserStaffDto sysUserStaffDto) {
        TokenInfoBo tokenInfo = LoginAspect.getTokenInfo();
        String hospitalBaseId = sysUserHospitalMapper.getHospitalBaseIdBySysUserId(tokenInfo.getUserId());
        sysUserStaffDto.setHospitalBaseId(hospitalBaseId);
        return ParamsMapUtil.getInstance()
                .addParam("hospitalBaseId", sysUserStaffDto.getHospitalBaseId())
                .addParam("realName", sysUserStaffDto.getRealName())
                .addParam("roleId", sysUserStaffDto.getRoleId())
                .addParam("hospitalDepartId", sysUserStaffDto.getHospitalDepartId())
                .addParam("pageIndex", sysUserStaffDto.getPageIndex())
                .addParam("pageSize", sysUserStaffDto.getPageSize());
    }

    @Override
    public void generateQrCode(String id, HttpServletResponse response) {
        SysUserHospital userHospital = sysUserHospitalMapper.selectByPrimaryKey(id);
        String encryptData = EncryptDataUtil.encryptData(CommonConstants.QRCODE_USER_STAFF, userHospital.getSysUserId());
        CodeUtil.encodeQrcode(userHospital.getRealName(), encryptData, response);
    }

    @Override
    public String getIdByUserId(String userId) {
        return sysUserHospitalMapper.getIdByUserId(userId);
    }

    @Override
    public void exportList(SysUserStaffDto sysUserStaffDto, HttpServletResponse response) {
        TokenInfoBo tokenInfo = LoginAspect.getTokenInfo();
        String hospitalBaseId = sysUserHospitalMapper.getHospitalBaseIdBySysUserId(tokenInfo.getUserId());
        List<SysUserStaffVo> list = sysUserHospitalMapper.getListByIds(sysUserStaffDto.getIds(), hospitalBaseId);
        try {
            // 不带标题
            ExcelUtil.exportExcel(list, SysUserStaffVo.class, "人员信息", new ExportParams(), response);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Transactional
    @Override
    public void importList(MultipartFile file) {
        TokenInfoBo tokenInfo = LoginAspect.getTokenInfo();
        String hospitalBaseId = sysUserHospitalMapper.getHospitalBaseIdBySysUserId(tokenInfo.getUserId());
        try {
            //获取工作薄
            Workbook workBook = ExcelUtil.getWorkBook(file);
            //循环工作表sheet
            for (int sheetNum = 0; sheetNum < workBook.getNumberOfSheets(); sheetNum++) {
                List<SysUserStaffVo> sysUserStaffVos = ExcelUtil.importExcel(file, sheetNum, 0, 1, SysUserStaffVo.class);
                if (CollectionUtil.isNullOrEmpty(sysUserStaffVos)) continue;
                //获取科室名
                String hospitalDepartName = workBook.getSheetName(sheetNum);
                //判断信息是否准确，并将准确的保存
                judgeAndSave(sysUserStaffVos,hospitalDepartName,hospitalBaseId);
            }
        } catch (IOException e) {
            throw new EpiCloudException("导入的信息错误！");
        }
    }

    /**
     * 判断导入的信息是否准确，并将信息保存
     *
     * @param sysUserStaffVos  员工集合
     * @param hospitalDepartName 医院科室名称
     * @param hospitalBaseId  医院信息id
     */
    private void judgeAndSave(List<SysUserStaffVo> sysUserStaffVos, String hospitalDepartName, String hospitalBaseId) {
        if (CollectionUtil.isNullOrEmpty(sysUserStaffVos)) return;
        for (SysUserStaffVo sysUserStaffVo : sysUserStaffVos) {
            sysUserStaffVo.setHospitalDepartName(hospitalDepartName);
            String roleId = "";
            String departId = "";
            // 判断科室与角色是否存在
            if (!StringUtil.isNullOrEmpty(sysUserStaffVo.getRoleName())) {
                roleId = sysRoleMapper.getIdByName(sysUserStaffVo.getRoleName(), hospitalBaseId);
                if (StringUtil.isNullOrEmpty(roleId)) {
                    throw new EpiCloudException(sysUserStaffVo.getRoleName() + ",角色不存在！");
                }
            }
            if (!StringUtil.isNullOrEmpty(sysUserStaffVo.getHospitalDepartName())) {
                departId = hospitalDepartMapper.getIdByName(sysUserStaffVo.getHospitalDepartName(), hospitalBaseId);
                if (StringUtil.isNullOrEmpty(departId)) {
                    throw new EpiCloudException(sysUserStaffVo.getHospitalDepartName() + ",科室不存在！");
                }
            }
            sysUserService.checkMobileExist(sysUserStaffVo.getMobile());
            // 检查身份证邮箱格式
            if (!StringUtil.isNullOrEmpty(sysUserStaffVo.getIdNumber()) && !RegExpUtil.match(sysUserStaffVo.getIdNumber(), RegExpUtil.ID_CARD)) {
                throw new EpiCloudException("身份证格式错误！");
            }
            if (!StringUtil.isNullOrEmpty(sysUserStaffVo.getEmail()) && !RegExpUtil.match(sysUserStaffVo.getEmail(), RegExpUtil.EMAIL)) {
                throw new EpiCloudException("邮箱格式错误！");
            }
            SysUserStaffDto sysUserStaffDto = ReflectUtil.copyProperties(sysUserStaffVo, SysUserStaffDto.class);
            SysUser sysUser = new SysUser(sysUserStaffDto);
            sysUserService.insert(sysUser);
            List<String> roleIds = new ArrayList<>();
            roleIds.add(roleId);
            sysRoleService.concatUser(roleIds, sysUser.getId());
            SysUserHospital sysUserHospital = new SysUserHospital(sysUserStaffDto);
            sysUserHospital.setSysUserId(sysUser.getId());
            sysUserHospital.setHospitalDepartId(departId);
            sysUserHospital.setHospitalBaseId(hospitalBaseId);
            sysUserHospitalMapper.insert(sysUserHospital);
        }
    }

    /**
     * 下载导入人员模板(下拉选项)
     *
     * @param response
     */
    @Override
    public void downloadTemplate(HttpServletResponse response) {
        TokenInfoBo tokenInfo = LoginAspect.getTokenInfo();
        String hospitalBaseId = sysUserHospitalMapper.getHospitalBaseIdBySysUserId(tokenInfo.getUserId());
        AssertUtil.isNull(hospitalBaseId,"获取医院id失败");
        Map<String, Object> paramMap = ParamsMapUtil.getInstance("hospitalBaseId", hospitalBaseId);
        //获取这个医院所有科室
        List<HospitalDepartVo> hospitalDepartVos = hospitalDepartMapper.getInfoListByCondition(paramMap);
        AssertUtil.isNull(CollectionUtil.isNullOrEmpty(hospitalDepartVos),"当前医院暂无科室");
        //获取所有角色
        List<SysRole> sysRoles = sysRoleMapper.selectListByCondition(paramMap);
        AssertUtil.isNull(CollectionUtil.isNullOrEmpty(sysRoles),"当前医院未配置角色");
        String[] roleNames = new String[sysRoles.size()];
        roleNames = sysRoles.stream().map(SysRole::getName).collect(Collectors.toList()).toArray(roleNames);
        //工作薄
        Workbook workbook = new HSSFWorkbook();
        //创建sheet
        for (int i = 0; i < hospitalDepartVos.size(); i++) {
            ExportParams exportParams = new ExportParams();
            //设置sheet名
            exportParams.setSheetName(hospitalDepartVos.get(i).getName());
            ExcelExportService excelExportService = new ExcelExportService();
            //创建sheet
            excelExportService.createSheet(workbook,exportParams,SysUserStaffVo.class,new ArrayList<>());
            //给每个sheet页的角色设置下拉选项
            ExcelUtil.selectList(workbook,i,1,1,roleNames);
        }
        //导出EXCEL
        try {
            ExcelUtil.downLoadExcel("人员信息",response,workbook);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void generateQrCode(List<String> ids, HttpServletResponse response) {
        List<Map<String, String>> encryptDataList = new ArrayList<>();
        for (String id : ids) {
            SysUserHospital sysUserHospital = sysUserHospitalMapper.selectByPrimaryKey(id);
            Map<String, String> map = new HashMap<>();
            map.put("name", sysUserHospital.getRealName());
            map.put("content", EncryptDataUtil.encryptData(CommonConstants.QRCODE_USER_STAFF, sysUserHospital.getSysUserId()));
            encryptDataList.add(map);
        }
        CodeUtil.getCodeZip(response, encryptDataList);
    }

    @Override
    public void remove(String id) {
        SysUserHospital sysUserHospital = sysUserHospitalMapper.selectByPrimaryKey(id);
        sysUserMapper.deleteByPrimaryKey(sysUserHospital.getSysUserId());
        sysRoleMapper.removeUser(sysUserHospital.getSysUserId());
        sysUserHospitalMapper.deleteByPrimaryKey(id);
    }
}